#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#define STACK_SIZE 2048
#define PRIOR_HIGH 19
#define PRIOR_LOW  18

osMutexId_t g_muxId; //定义互斥锁

void TaskHigh ( void *arg ){
    (void*)arg;

    printf("[TaskHigh] Start, Sleep 100ticks\r\n");
    osDelay( 100 );//休眠让低优先级先获取锁

    // 申请互斥锁 10tick
    printf("[TaskHigh] Try to Acuqire Mutex, 10ticks\r\n");
    if (osMutexAcquire( g_muxId, 10) == osOK) {
        printf("[TaskHigh] Acuqire Mutex OK\r\n");

        printf("[TaskHigh] Release Mutex\r\n");
        osMutexRelease( g_muxId ); // 释放互斥锁
        return;
    }
    printf("[TaskHigh] Acuqire Mutex Timeout\r\n");


    // 申请互斥锁 , 永久等待
    printf("[TaskHigh] Try to Acuqire Mutex, Forever\r\n");
    if (osMutexAcquire(g_muxId, osWaitForever) != osOK) {
        printf("[TaskHigh] Acquire Mutex Error\r\n");
        return;
    }

    printf("[TaskHigh] Acquire Mutex OK\r\n");

    printf("[TaskHigh] Release Mutex\r\n");
    osMutexRelease ( g_muxId );     // 释放互斥锁

    printf("[TaskHigh] Exit\r\n");
    return;
}

void TaskLow( void * arg ){
    (void*)arg;

    printf("[TaskLow] Sart\r\n");

    // 申请互斥锁
    printf("[TaskLow] Try to Acquire Mutex\r\n");
    osMutexAcquire(g_muxId, osWaitForever);
    printf("[TaskLow] Acquire Mutex OK\r\n");

    // 任务休眠 200 Ticks
    printf("[TaskLow] Sleep 200Ticks\r\n");
    for(int i=0; i<200; i++){
     osDelay( 1 );
    }
    printf("[TaskLow] Resume\r\n");

    // 释放互斥锁
    printf("[TaskLow] Release Mutex\r\n");
    osMutexRelease( g_muxId );

    printf("[TaskLow] Exit\r\n");
    return;
}

static void MutexDemoMain( void ){
    osMutexAttr_t attrMutex;
    osThreadAttr_t attrTask;

    // 创建互斥锁
    if( (g_muxId = osMutexNew( &attrMutex ) ) == NULL) {
        printf("[Main] Mutex Create Failed\r\n");
        return;
    }
    printf("[Main] Mutex Create OK\r\n");

    // 先锁定任务调度，防止新创建的任务比本任务高而发生调度
    osKernelLock();

    // 创建高优先级任务
    attrTask.name = "TaskHigh";
    attrTask.attr_bits  = 0U;
    attrTask.cb_mem     = NULL;
    attrTask.cb_size    = 0U;
    attrTask.stack_mem  = NULL;
    attrTask.stack_size = STACK_SIZE;
    attrTask.priority   = PRIOR_HIGH;
    if (osThreadNew((osThreadFunc_t)TaskHigh, NULL, &attrTask) == NULL) {
        printf("[Main] Create TaskHigh Failed\r\n");
        return;
    }
    printf("[Main] Create TaskHigh OK\r\n");

    attrTask.name = "TaskLow";
    attrTask.attr_bits  = 0U;
    attrTask.cb_mem     = NULL;
    attrTask.cb_size    = 0U;
    attrTask.stack_mem  = NULL;
    attrTask.stack_size = STACK_SIZE;
    attrTask.priority   = PRIOR_LOW;
    if( osThreadNew((osThreadFunc_t)TaskLow, NULL, &attrTask) == NULL) {
        printf("[Main] Create TaskLow Failed\r\n");
        return;
    }
    printf("[Main] Create TaskLow OK\r\n");

    // 解锁任务调度，此时会发生任务调度，执行就绪队列中最高优先级任务
    osKernelUnlock();
}

SYS_RUN( MutexDemoMain );
